package com.example.shoppingmallspringboot.config;



import com.example.shoppingmallspringboot.util.FwResult;
import com.example.shoppingmallspringboot.util.JwtConstant;
import com.example.shoppingmallspringboot.util.JwtUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Configuration
public class JwtAuthenticationFilter extends OncePerRequestFilter {
    @Autowired
    RedisTemplate redisTemplate;
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
       System.out.println("当前的访问路径是"+request.getRequestURI());
        /* 根据项目的实际需求设置白名单URL，即白名单中的URL不需要判断token是否正确，其它都要判断token是否正确*/
        List<String> WHITE_LIST = new ArrayList<String>() {{
            add("/swagger-ui");
            add("/v3/api-docs");
            add("/swiper"); //add("/static/"); // 静态资源路径
            add("/images");
            add("/home"); //前台首页
            add("/goods");//商品页
            add("/category");//商品页
            add("/login");
            add("/uniAppLogin");
            add("/register"); // 前台账号（登录、注册）
        }};
        for (String url : WHITE_LIST) {
            if (request.getRequestURI().indexOf(url) >= 0) {
                filterChain.doFilter(request, response);//继续执行原有的请求
                return;
            }
        }
        /* 获取header中的token信息 */
        String token = request.getHeader(JwtConstant.HEADER_NAME);
        System.out.println("token"+token);
        response.setCharacterEncoding("UTF-8");
        //如果不包含token，则显示“token格式出错”，直接返回
        if (StringUtils.isEmpty(token)) {
            response.setContentType("application/json;charset=utf-8;");
            response.setStatus(HttpStatus.UNAUTHORIZED.value());
            ObjectMapper objectMapper=new ObjectMapper();
            String result= objectMapper.writeValueAsString( FwResult.failedMsg("token格式出错"));
            response.getWriter().write(result);
            return;
        }

        //如果验证token失败则显示“token验证失败”，直接返回
        if (!JwtUtil.verifyToken(token)) {
            response.setContentType("application/json;charset=utf-8;");
            response.setStatus(HttpStatus.UNAUTHORIZED.value());
            ObjectMapper objectMapper=new ObjectMapper();
            String result= objectMapper.writeValueAsString( FwResult.failedMsg("token验证失败"));
            response.getWriter().write(result);
            return;
        }

        //token是合法的，则判断token是否在有效期之内
        Object tokenObject=redisTemplate.opsForValue().get(token);//获取缓存中键为token的值，如果缓存过期则返回null
        if (tokenObject==null) {
            response.setContentType("application/json;charset=utf-8;");
            response.setStatus(HttpStatus.UNAUTHORIZED.value());
            ObjectMapper objectMapper=new ObjectMapper();
            String result= objectMapper.writeValueAsString( FwResult.failedMsg("登录过期，请重新登录"));
            response.getWriter().write(result);
        } else {
            //更新缓存的有效期
            redisTemplate.expire(token, 20, TimeUnit.MINUTES);//将键为token的缓存对象的有效期设置为20分钟
            filterChain.doFilter(request, response);
        }
    }
}

